package com.swiot.biz.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.swiot.biz.constants.TemplateConstants;
import com.swiot.biz.domain.Template;
import com.swiot.biz.mapper.TemplateMapper;
import com.swiot.biz.service.ITemplateService;
import com.swiot.biz.utils.LuckysheetDataParser;
import com.swiot.biz.utils.SqlGenerator;
import com.swiot.common.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 模板基础Service业务层处理
 *
 * @author kingdom
 * @date 2025-08-25
 */
@Service
public class TemplateServiceImpl implements ITemplateService {
    private static final Logger log = LoggerFactory.getLogger(TemplateServiceImpl.class);

    @Autowired
    private TemplateMapper templateMapper;

    @Autowired
    private LuckysheetDataParser luckysheetDataParser;

    @Autowired
    private SqlGenerator sqlGenerator;

    /**
     * 查询模板基础
     *
     * @param id 模板基础主键
     * @return 模板基础
     */
    @Override
    public Template selectTemplateById(String id) {
        return templateMapper.selectTemplateById(id);
    }

    /**
     * 查询模板基础列表
     *
     * @param template 模板基础
     * @return 模板基础
     */
    @Override
    public List<Template> selectTemplateList(Template template) {
        template.setDelFlag(TemplateConstants.DeleteStatus.NORMAL);
        return templateMapper.selectTemplateList(template);
    }

    /**
     * 新增模板基础
     *
     * @param template 模板基础
     * @return 结果
     */
    @Override
    public int insertTemplate(Template template) {
        // 检查模板名是否已存在
        if (template.getTemplateName() != null && !template.getTemplateName().trim().isEmpty()) {
            Template existingTemplate = templateMapper.selectTemplateByName(template.getTemplateName().trim());
            if (existingTemplate != null) {
                throw new ServiceException("模板名已存在");
            }
        }


        return templateMapper.insertTemplate(template);
    }

    /**
     * 修改模板基础
     *
     * @param template 模板基础
     * @return 结果
     */
    @Override
    public int updateTemplate(Template template) {
        log.info("开始更新模板，模板ID：{}，模板名称：{}", template.getId(), template.getTemplateName());

        // 编辑功能只更新业务字段，不涉及SQL生成和表创建
        return templateMapper.updateTemplate(template);
    }

    /**
     * 发布模板
     *
     * @param template 模板对象
     * @return 结果
     */
    @Override
    public int publishTemplate(Template template) {
        log.info("开始发布模板，模板ID：{}，模板名称：{}", template.getId(), template.getTemplateName());
        // 从luckysheet数据中提取字段信息
        List<String> fields = luckysheetDataParser.extractFieldsFromLuckysheet(
                template.getTemplateContent(),
                template.getFieldRowCol()
        );
        List<String> alarms = luckysheetDataParser.extractFieldsFromLuckysheet(
                template.getTemplateContent(),
                template.getAlarmRowCol()
        );
        JSONObject fieldsObjects = luckysheetDataParser.extractFieldsObjectsFromLuckysheet(
                template.getTemplateContent(),
                Integer.parseInt(template.getFieldRowCol().split(TemplateConstants.ROW_COL_SEPARATOR)[0]),
                Integer.parseInt(template.getFieldRowCol().split(TemplateConstants.ROW_COL_SEPARATOR)[1]),
                Integer.parseInt(template.getDataRowCol().split(TemplateConstants.ROW_COL_SEPARATOR)[1]),
                Integer.parseInt(template.getAlarmRowCol().split(TemplateConstants.ROW_COL_SEPARATOR)[1])
        );

        // 生成表名
        String tableName = sqlGenerator.generateTableName(template.getTemplateName(), TemplateConstants.DEFAULT_TABLE_SUFFIX);
        String tableAlarm = sqlGenerator.generateTableName(template.getTemplateName(), TemplateConstants.DEFAULT_ALARM_SUFFIX);

        template.setTemplateTable(tableName);
        template.setTemplateTableAlarm(tableAlarm);

        // 解析luckysheet数据并生成SQL
        String createTableSQL = parseLuckysheetAndGenerateSQL(fields, template, tableName);
        String createAlarmSQL = parseLuckysheetAndGenerateSQL(fields, template, tableAlarm);


        // 执行创建表SQL
        if (createTableSQL != null && !createTableSQL.trim().isEmpty()) {
            try {
                log.info("开始执行创建表SQL");
                int result = templateMapper.executeCreateTableSQL(createTableSQL);
                result = templateMapper.executeCreateTableSQL(createAlarmSQL);
                log.info("创建表SQL执行完成，结果：{}", result);
            } catch (Exception e) {
                log.error("执行创建表SQL时发生错误：", e);
                throw new RuntimeException(TemplateConstants.ErrorMessages.CREATE_TABLE_FAILED + "：" + e.getMessage());
            }
        }

        int fieldsSize = Integer.parseInt(template.getFieldRowCol().split(TemplateConstants.ROW_COL_SEPARATOR)[1]);
        int alarmsSize = Integer.parseInt(template.getAlarmRowCol().split(TemplateConstants.ROW_COL_SEPARATOR)[1]);
        String content = luckysheetDataParser.convertToView(template.getTemplateContent(), fieldsSize, alarmsSize);
        template.setTemplateContentView(content);
        template.setFieldRowKey(JSONArray.from(fields).toString());
        template.setAlarmRowKey(JSONArray.from(alarms).toString());
        template.setFieldObject(fieldsObjects.toString());

        // 更新模板信息（包含发布状态）
        return templateMapper.updateTemplate(template);
    }

    /**
     * 批量删除模板基础
     *
     * @param ids 需要删除的模板基础主键
     * @return 结果
     */
    @Override
    public int deleteTemplateByIds(String[] ids) {
        return templateMapper.deleteTemplateByIds(ids);
    }

    /**
     * 删除模板基础信息
     *
     * @param id 模板基础主键
     * @return 结果
     */
    @Override
    public int deleteTemplateById(String id) {
        return templateMapper.deleteTemplateById(id);
    }

    /**
     * 从luckysheet数据中提取指定行列的数据
     *
     * @param templateContent luckysheet组件数据
     * @param rowCol          行列格式字符串，如"1:2"
     * @return 提取的数据
     */
    @Override
    public String extractDataFromLuckysheet(String templateContent, String rowCol) {
        return luckysheetDataParser.extractDataFromLuckysheet(templateContent, rowCol);
    }

    /**
     * 解析luckysheet数据并生成创建表SQL
     *
     * @param template 模板对象
     * @return 创建表SQL语句
     */
    private String parseLuckysheetAndGenerateSQL(List<String> fields, Template template, String tableName) {
        try {
            log.info("开始解析luckysheet数据并生成SQL，模板名称：{}", template.getTemplateName());


            if (fields.isEmpty()) {
                log.warn("未提取到字段信息，跳过SQL生成");
                return "";
            }
            // 检查字段重复性
            if (hasDuplicateFields(fields)) {
                log.error("检测到重复字段，模板名称：{}", template.getTemplateName());
                throw new RuntimeException(TemplateConstants.ErrorMessages.DUPLICATE_FIELDS_ERROR);
            }


            // 将生成的表名赋值给template的templateTable字段

            log.info("设置模板表名：{}", tableName);

            // 检查表是否存在
            int tableExists = templateMapper.checkTableExists(tableName);
            log.info("检查表是否存在，表名：{}，存在结果：{}", tableName, tableExists);

            String sqlStatement;
            if (tableExists == 0) {
                // 表不存在，生成CREATE TABLE SQL
                log.info("表不存在，生成CREATE TABLE SQL，表名：{}", tableName);
                String groupName = template.getTemplateDescription() != null ?
                        template.getTemplateDescription() : TemplateConstants.DEFAULT_GROUP_NAME;
                sqlStatement = sqlGenerator.generateCreateTableSQL(tableName, fields, groupName);
            } else {
                // 表存在，检查字段并生成ALTER TABLE SQL
                log.info("表已存在，检查字段并生成ALTER TABLE SQL，表名：{}", tableName);
                sqlStatement = generateAlterTableSQLWithFieldCheck(tableName, fields);
            }

            log.info("SQL生成完成，表名：{}，字段数量：{}", tableName, fields.size());

            return sqlStatement;

        } catch (Exception e) {
            log.error("解析luckysheet数据并生成SQL时发生错误：", e);
            throw new RuntimeException(TemplateConstants.ErrorMessages.PARSE_TEMPLATE_FAILED + "：" + e.getMessage());
        }
    }

    /**
     * 检查字段列表中是否存在重复字段
     *
     * @param fields 字段列表
     * @return 如果存在重复字段返回true，否则返回false
     */
    private boolean hasDuplicateFields(List<String> fields) {
        if (fields == null || fields.isEmpty()) {
            return false;
        }

        // 使用Set来检查重复，Set不允许重复元素
        java.util.Set<String> uniqueFields = new java.util.HashSet<>();

        for (String field : fields) {
            if (field != null && !field.trim().isEmpty()) {
                // 如果添加失败，说明字段已存在（重复）
                if (!uniqueFields.add(field.trim())) {
                    log.warn("发现重复字段：{}", field);
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * 生成ALTER TABLE SQL，并检查字段是否存在
     *
     * @param tableName 表名
     * @param fields    字段列表
     * @return ALTER TABLE SQL语句
     */
    private String generateAlterTableSQLWithFieldCheck(String tableName, List<String> fields) {
        try {
            log.info("开始检查字段并生成ALTER TABLE SQL，表名：{}，字段数量：{}", tableName, fields.size());

            // 一次性查询表的所有字段
            List<String> existingColumns = templateMapper.getTableColumns(tableName);
            log.info("查询到表 {} 的现有字段数量：{}", tableName, existingColumns.size());

            // 将现有字段转换为Set，提高查找效率
            java.util.Set<String> existingColumnSet = new java.util.HashSet<>(existingColumns);

            StringBuilder sql = new StringBuilder();
            int addedFieldsCount = 0;

            sql.append("ALTER TABLE `").append(tableName).append("` \n");
            // 检查每个字段是否存在
            for (String field : fields) {
                String fieldName = sqlGenerator.convertToValidFieldName(field);
                log.info("检查字段是否存在：原始字段名='{}'，生成字段名='{}'", field, fieldName);
                // 在本地Set中检查字段是否存在
                if (!existingColumnSet.contains(fieldName)) {
                    // 字段不存在，生成ADD COLUMN语句
                    sql.append("ADD COLUMN `").append(fieldName).append("` VARCHAR(25) NULL ");
                    sql.append("COMMENT '").append(escapeSqlComment(field)).append("',\n");
                    addedFieldsCount = addedFieldsCount + 1;
                } else {
                    // 字段已存在，跳过
                    log.info("字段已存在，跳过：{}", fieldName);
                }
            }
            sql.deleteCharAt(sql.length() - 1);
            sql.deleteCharAt(sql.length() - 1);
            sql.append(";");

            String resultSql = sql.toString();
            log.info("生成ALTER TABLE SQL完成，表名：{}，添加字段数量：{}，SQL长度：{}",
                    tableName, addedFieldsCount, resultSql.length());
            log.debug("生成的SQL：\n{}", resultSql);

            return resultSql;

        } catch (Exception e) {
            log.error("生成ALTER TABLE SQL时发生错误：", e);
            throw new RuntimeException("生成ALTER TABLE SQL失败：" + e.getMessage());
        }
    }

    /**
     * 转义SQL注释中的特殊字符
     *
     * @param comment 原始注释
     * @return 转义后的注释
     */
    private String escapeSqlComment(String comment) {
        if (comment == null) {
            return "";
        }
        // 转义单引号
        return comment.replace("'", "''");
    }
}
